home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / gnulib / libsrc98.zoo / read.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  6.0 KB  |  336 lines

  1. /*
  2.  *        Cross Development System for Atari ST 
  3.  *     Copyright (c) 1988, Memorial University of Newfoundland
  4.  *
  5.  * See ChangeLog for further history  ++jrb
  6.  *
  7.  * 1.5        ERS    modified for benefit of 16 bit compilers
  8.  * 1.4        ERS
  9.  *     Changed BIOS calls into GEMDOS calls.
  10.  *
  11.  * 1.3        jrd
  12.  *
  13.  * Revision 1.2  88/02/03  22:56:30  m68k
  14.  * Added unix like tty driver stuff
  15.  * 
  16.  * Revision 1.1  88/01/29  17:31:39  m68k
  17.  * Initial revision
  18.  * 
  19.  */
  20. #include    <osbind.h>
  21. #include    <ioctl.h>
  22. #include    <signal.h>
  23. #include    <tchars.h>
  24. #include    <unistd.h>
  25. #include    <device.h>
  26. #include    <limits.h>
  27. #include     <errno.h>
  28. #include    "lib.h"
  29. #ifndef _COMPILER_H
  30. #include <compiler.h>
  31. #endif
  32.  
  33. #define    iswhite(c)    ((c) == ' ' || (c) == '\t')
  34. #define    isvisable(c)    ((unsigned char)(c) >= ' ')
  35. #define echochar(fd, c) ((void)((__ttymode & ECHO) && _echochar((fd), (c))))
  36. #define delchar(fd, n)  ((void)((__ttymode & ECHO) ?  \
  37.                                                 _delchar((fd), (n)),0 : 0 ))
  38.  
  39. extern int    errno;
  40. extern int    __col_pos;    /* defined in write.c */
  41. static int    start_col;
  42. static char    *thebuf;
  43.  
  44. static int _echochar __PROTO((int fd, int c));
  45. static void _delchar __PROTO((int fd, int n));
  46. static int str_length __PROTO((char *p, int n));
  47.  
  48. extern unsigned int console_read_byte(int);
  49. extern void console_write_byte(int, int);
  50. extern int console_input_status(int);
  51.  
  52. #ifdef __MSHORT__
  53. int
  54. read(fd, buf, nbytes)
  55.     int    fd;
  56.     void    *buf;
  57.     unsigned int    nbytes;
  58. {
  59.       return (int)(_read(fd, buf, (unsigned long) nbytes));
  60. }
  61.  
  62. #else
  63.  
  64. asm(".stabs \"_read\",5,0,0,__read"); /* dept of clean tricks */
  65.  
  66. #endif
  67.  
  68. long
  69. _read(fd, buf, n)
  70.         int     fd;
  71.         void    *buf;
  72.         unsigned long    n;
  73.   {
  74.     long        rval, nbytes;
  75.     long            cnt = 0;
  76.     char        *p = buf;
  77.     struct _device    *dev;
  78.  
  79.     if(n > ((unsigned long)LONG_MAX))
  80.     {
  81.         errno = EBADARG;
  82.         return -1L;
  83.     }
  84.  
  85.     nbytes = (long)n;
  86.     if ((dev = _dev_fd(fd)) && dev->read)
  87.         return (*dev->read)(fd, buf, nbytes);
  88.  
  89.     if (!isatty(fd))
  90.         { /* really cant do much about the signdness of nbytes here */
  91.         if ((rval = Fread(fd, nbytes, buf)) < 0) 
  92.             {
  93.             errno = -rval;
  94.             rval = -1;
  95.             }
  96.         return rval;
  97.         }
  98.     thebuf = buf;
  99.     start_col = __col_pos;
  100.     while (1) {
  101.         *p = console_read_byte(fd);
  102.         if (__ttymode & RAW) 
  103.             {
  104.             if (__ttymode & ECHO) 
  105.                 {
  106.                 console_write_byte(fd, *p);
  107.                 if (*p == '\r')
  108.                     __col_pos = 0;
  109.                 else if (isvisable(*p))
  110.                     __col_pos++;
  111.                 }
  112.             if (++cnt >= nbytes || !console_input_status(fd))
  113.                 return cnt;
  114.             p++;
  115.             continue;
  116.             }
  117.         if ((__ttymode & CRMOD) && *p == '\r')
  118.             *p = '\n';
  119.         if (*p == __tchars[TC_INTRC]) 
  120.             {
  121.             /* Do the bsd thing here, i.e. flush buffers
  122.              * and continue to read after the interupt
  123.              */
  124.             echochar(fd, *p);
  125.             p = buf;
  126.             cnt = 0;
  127.             raise(SIGINT);
  128.             } 
  129.             else 
  130.         if (*p == __tchars[TC_QUITC]) 
  131.             {
  132.             echochar(fd, *p);
  133.             p = buf;
  134.             cnt = 0;
  135.             raise(SIGQUIT);
  136.             }
  137.         if (__ttymode & CBREAK) 
  138.             {
  139.             if (*p == __tchars[TC_LNEXTC])
  140.                 *p = console_read_byte(fd);
  141.             if (__ttymode & ECHO) 
  142.                 {
  143.                 if (*p == '\n' && (__ttymode & CRMOD)) 
  144.                     {
  145.                     console_write_byte(fd, '\n');
  146.                     console_write_byte(fd, '\r');
  147.                     __col_pos = 0;
  148.                     } 
  149.                     else
  150.                     (void) _echochar(fd, *p);
  151.                 }
  152.             ++cnt;
  153.  
  154.             if (!console_input_status(fd))
  155.                 return cnt;
  156.             p++;
  157.             } 
  158.             else
  159.         if (*p == __tchars[TC_LNEXTC]) 
  160.             {
  161.             if (__ttymode & ECHO) 
  162.                 {
  163.                 console_write_byte(fd, '^');
  164.                 console_write_byte(fd, '\b');
  165.                 }
  166.             *p = console_read_byte(fd);
  167.             echochar(fd, *p++);
  168.             cnt++;
  169.             }
  170.             else
  171.         if (*p == __tchars[TC_EOFC]) 
  172.             {
  173.             if (__ttymode & ECHO)
  174.                 {
  175.                 int i = _echochar(fd, *p);
  176.                 __col_pos -= i;
  177.                 while (i-- > 0)
  178.                     console_write_byte(fd, '\b');
  179.                 }
  180.             return cnt;
  181.             }
  182.             else
  183.         if (*p == '\n' || *p == __tchars[TC_BRKC]) 
  184.             {
  185.             if (__ttymode & ECHO)
  186.                 if (*p == '\n')
  187.                     {
  188.                     console_write_byte(fd, '\n');
  189.                     if (__ttymode & CRMOD) 
  190.                         {
  191.                         console_write_byte(fd, '\r');
  192.                         __col_pos = 0;
  193.                         }
  194.                     }
  195.                     else
  196.                     (void) _echochar(fd, *p);
  197.             return ++cnt;
  198.             }
  199.             else
  200.         if ((*p == __tchars[TC_ERASE]) || (*p == __tchars[TC_ERASE]))
  201.             {
  202.             if (cnt) 
  203.                 {
  204.                 --p; --cnt;
  205.                 delchar(fd, (int)cnt);
  206.                 }
  207.             }
  208.             else
  209.         if (*p == __tchars[TC_KILL]) 
  210.             {
  211.             while (--cnt >= 0) 
  212.                 {
  213.                 delchar(fd, (int)cnt);
  214.                 p--;
  215.                 }
  216.             cnt = 0;
  217.             } 
  218.             else
  219.         if (*p == __tchars[TC_WERASC]) 
  220.             {
  221.             p--;
  222.             while (cnt && iswhite(*p)) 
  223.                 {
  224.                 --p; --cnt;
  225.                 delchar(fd, (int)cnt);
  226.                 }
  227.             while (cnt && !iswhite(*p)) 
  228.                 {
  229.                 --p; --cnt;
  230.                 delchar(fd, (int)cnt);
  231.                 }
  232.             p++;
  233.             }
  234.             else
  235.         if (*p == __tchars[TC_RPRNTC]) 
  236.             {
  237.             char    *s;
  238.  
  239.             echochar(fd, __tchars[TC_RPRNTC]);
  240.             console_write_byte(fd, '\r');
  241.             console_write_byte(fd, '\n');
  242.             __col_pos = 0;
  243.             start_col = 0;
  244.             if (__ttymode & ECHO)
  245.                 for (s = buf ; s < p ; s++)
  246.                     echochar(fd, *s);
  247.             }
  248.             else
  249.             {
  250.             echochar(fd, *p); p++;
  251.             cnt++;
  252.             }
  253.         if (cnt >= nbytes)
  254.             return cnt;
  255.     }
  256.     /*NOTREACHED*/
  257. }
  258.  
  259. static    int
  260. _echochar(fd, c)
  261.     int    fd;
  262.     int    c;
  263. {
  264.     int    len = 0;
  265.  
  266.     c &= 0xff;
  267.     if (c < ' ') {
  268.         if (c == '\t') {
  269.             int    i;
  270.  
  271.             len = ((__col_pos | 7) + 1) - __col_pos;
  272.             if (__ttymode & XTABS)
  273.                 for (i = len ; i-- ;)
  274.                     console_write_byte(fd, ' ');
  275.             else
  276.                 console_write_byte(fd, '\t');
  277.         } else {
  278.             console_write_byte(fd, '^');
  279.             console_write_byte(fd, c + 0x40);
  280.             len += 2;
  281.         }
  282.     } else if (c == 0x7f) {
  283.         console_write_byte(fd, '^');
  284.         console_write_byte(fd, '?');
  285.         len += 2;
  286.     } else {
  287.         console_write_byte(fd, c);
  288.         len++;
  289.     }
  290.     __col_pos += len;
  291.     return len;
  292. }
  293.  
  294. static    void
  295. _delchar(fd, n)
  296.     int    fd, n;
  297. {
  298.     int    len = 0;
  299.     char    c = thebuf[n];
  300.  
  301.     if ((c >= 0 && c < ' ') || c == 0x7f) {
  302.         if (c == '\t')
  303.             len = __col_pos - str_length(thebuf, n);
  304.         else
  305.             len += 2;
  306.     } else
  307.         len++;
  308.     __col_pos -= len;
  309.     while (len--) {
  310.         console_write_byte(fd, '\b');
  311.         console_write_byte(fd, ' ');
  312.         console_write_byte(fd, '\b');
  313.     }
  314. }
  315.  
  316. static    int
  317. str_length(p, n)
  318.     char    *p;
  319.     int    n;
  320. {
  321.     int    pos = start_col;
  322.     char    c;
  323.  
  324.     while (n--) {
  325.         c = *p++;
  326.         if ((c >= 0 && c < ' ') || c == 0x7f)
  327.             if (c == '\t')
  328.                 pos = (pos | 7) + 1;
  329.             else
  330.                 pos += 2;
  331.         else
  332.             pos++;
  333.     }
  334.     return pos;
  335. }
  336.